package com.gosling.cloudspace.tools;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 时间工具类: 兼容各种格式转换
 * ONE:分隔符-
 * TWO:分隔符/
 * THREE:无分隔符
 *
 * @Software: IntelliJ IDEA
 * @Addresses: www.gosling.com
 * @Email 1793327033@qq.com
 * @Classname DateTool
 * @Author: lihonglin
 * @Date: 2021/12/22 14:55
 */
public class DateTool {
    public final static List<String> DATE_STR_LIST = new ArrayList<>();
    public final static Map<String, SimpleDateFormat> dateStrMap = new HashMap<>(8);
    public final static String ONE_YYYY_MM_DD = "yyyy-MM-dd";
    public final static String TWO_YYYY_MM_DD = "yyyy/MM/dd";
    public final static String THREE_MMDDHHMMSS = "MMddHHmmss";
    public final static String THREE_YYYYMMDDHHMM = "yyyyMMddHHmm";
    public final static String THREE_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    public final static String ONE_YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
    public final static String TWO_YYYY_MM_DD_HH_MM = "yyyy/MM/dd HH:mm";
    public final static String ONE_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    public final static String TWO_YYYY_MM_DD_HH_MM_SS = "yyyy/MM/dd HH:mm:ss";
    public final static String USA_YYYY_MM_DD_HH_MM_SS = "EEE MMM dd HH:mm:ss zzz yyyy";
    protected static final Logger logger = LoggerFactory.getLogger(DateTool.class);
    public static SimpleDateFormat SDF_YYYY_MM_DD;
    public static SimpleDateFormat SDF_MMDDHHMMSS;
    public static SimpleDateFormat SDF_YYYYMMDDHHMM;
    public static SimpleDateFormat SDF_YYYYMMDDHHMMSS;
    public static SimpleDateFormat SDF_YYYY_MM_DD_HH_MM;
    public static SimpleDateFormat SDF_SIMPLE_YYYY_MM_DD;
    public static SimpleDateFormat SDF_YYYY_MM_DD_HH_MM_SS;
    public static SimpleDateFormat SDF_SIMPLE_YYYY_MM_DD_HH_MM;
    public static SimpleDateFormat SDF_USA_YYYY_MM_DD_HH_MM_SS;
    public static SimpleDateFormat SDF_SIMPLE_YYYY_MM_DD_HH_MM_SS;

    static {
        SDF_YYYY_MM_DD = new SimpleDateFormat(ONE_YYYY_MM_DD);
        SDF_MMDDHHMMSS = new SimpleDateFormat(THREE_MMDDHHMMSS);
        SDF_YYYYMMDDHHMM = new SimpleDateFormat(THREE_YYYYMMDDHHMM);
        SDF_SIMPLE_YYYY_MM_DD = new SimpleDateFormat(TWO_YYYY_MM_DD);
        SDF_YYYYMMDDHHMMSS = new SimpleDateFormat(THREE_YYYYMMDDHHMMSS);
        SDF_YYYY_MM_DD_HH_MM = new SimpleDateFormat(ONE_YYYY_MM_DD_HH_MM);
        SDF_YYYY_MM_DD_HH_MM_SS = new SimpleDateFormat(ONE_YYYY_MM_DD_HH_MM_SS);
        SDF_SIMPLE_YYYY_MM_DD_HH_MM = new SimpleDateFormat(TWO_YYYY_MM_DD_HH_MM);
        SDF_SIMPLE_YYYY_MM_DD_HH_MM_SS = new SimpleDateFormat(TWO_YYYY_MM_DD_HH_MM_SS);
        SDF_USA_YYYY_MM_DD_HH_MM_SS = new SimpleDateFormat(USA_YYYY_MM_DD_HH_MM_SS, Locale.US);
        DATE_STR_LIST.add(ONE_YYYY_MM_DD);
        DATE_STR_LIST.add(TWO_YYYY_MM_DD);
        DATE_STR_LIST.add(THREE_MMDDHHMMSS);
        DATE_STR_LIST.add(THREE_YYYYMMDDHHMM);
        DATE_STR_LIST.add(THREE_YYYYMMDDHHMMSS);
        DATE_STR_LIST.add(ONE_YYYY_MM_DD_HH_MM);
        DATE_STR_LIST.add(TWO_YYYY_MM_DD_HH_MM);
        DATE_STR_LIST.add(ONE_YYYY_MM_DD_HH_MM_SS);
        DATE_STR_LIST.add(TWO_YYYY_MM_DD_HH_MM_SS);
        DATE_STR_LIST.add(USA_YYYY_MM_DD_HH_MM_SS);
        dateStrMap.put(ONE_YYYY_MM_DD, SDF_YYYY_MM_DD);
        dateStrMap.put(THREE_MMDDHHMMSS, SDF_MMDDHHMMSS);
        dateStrMap.put(THREE_YYYYMMDDHHMM, SDF_YYYYMMDDHHMM);
        dateStrMap.put(TWO_YYYY_MM_DD, SDF_SIMPLE_YYYY_MM_DD);
        dateStrMap.put(THREE_YYYYMMDDHHMMSS, SDF_YYYYMMDDHHMMSS);
        dateStrMap.put(ONE_YYYY_MM_DD_HH_MM, SDF_YYYY_MM_DD_HH_MM);
        dateStrMap.put(ONE_YYYY_MM_DD_HH_MM_SS, SDF_YYYY_MM_DD_HH_MM_SS);
        dateStrMap.put(TWO_YYYY_MM_DD_HH_MM, SDF_SIMPLE_YYYY_MM_DD_HH_MM);
        dateStrMap.put(TWO_YYYY_MM_DD_HH_MM_SS, SDF_SIMPLE_YYYY_MM_DD_HH_MM_SS);
        dateStrMap.put(USA_YYYY_MM_DD_HH_MM_SS, SDF_USA_YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 传入时间字符串 支持多种格式兼容
     * <p>
     * yyyy-MM-dd 2022-4-15
     * yyyy/MM/dd 2022/4/15
     * yyyyMMddHHmm 202204151440
     * yyyyMMddHHmmss 20220415144049
     * yyyy-MM-dd HH:mm 2022-4-15 14:40
     * yyyy/MM/dd HH:mm 2022/4/15 14:40
     * yyyy-MM-dd HH:mm:ss 2022-4-15 14:40:49
     * yyyy/MM/dd HH:mm:ss 2022/4/15 14:40:49
     * EEE MMM dd HH:mm:ss zzz yyyy Fri Apr 15 14:40:49 CST 2022
     *
     * @param dateString
     * @return {@link Date}
     * @author lihonglin
     * @date 2022/4/15 14:40
     */
    public static Date dateAtWillFormat(String dateString) {
        if (StringUtils.isBlank(dateString)) {
            return now();
        }
        Date date = null;
        try {
            date = SDF_YYYY_MM_DD.parse(dateString);
        } catch (Exception e) {
            System.out.println("1");
            try {
                date = SDF_YYYYMMDDHHMMSS.parse(dateString);
            } catch (Exception e1) {
                try {
                    date = SDF_YYYYMMDDHHMM.parse(dateString);
                } catch (Exception e2) {
                    try {
                        date = SDF_SIMPLE_YYYY_MM_DD.parse(dateString);
                    } catch (Exception e3) {
                        try {
                            date = SDF_YYYY_MM_DD_HH_MM.parse(dateString);
                        } catch (Exception e4) {
                            try {
                                date = SDF_YYYY_MM_DD_HH_MM_SS.parse(dateString);
                            } catch (Exception e5) {
                                try {
                                    date = SDF_USA_YYYY_MM_DD_HH_MM_SS.parse(dateString);
                                } catch (ParseException e6) {
                                    try {
                                        date = SDF_SIMPLE_YYYY_MM_DD_HH_MM.parse(dateString);
                                    } catch (ParseException e7) {
                                        try {
                                            date = SDF_SIMPLE_YYYY_MM_DD_HH_MM_SS.parse(dateString);
                                        } catch (ParseException e8) {
                                            try {
                                                date = SDF_MMDDHHMMSS.parse(dateString);
                                            } catch (ParseException e9) {
                                                logger.error("无可用的时间格式进行转换！");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return date;
    }

    public static void main(String[] args) {
        System.out.println(dateAtWillFormat("2024-01-01 11:11:11").toString());
    }

    /***
     * 传入时间字符串 支持多种格式兼容
     *
     * @param dateString
     * @return
     */
    public static Date dateAtWillFormat2(String dateString) {
        return StringUtils.isBlank(dateString) ? now() : dateStrFormat(dateString);
    }

    public static Date dateStrFormat(String dateString) {
        Date date = null;
        for (String dateStr : DATE_STR_LIST) {
            try {
                SimpleDateFormat format = dateStrMap.get(dateStr);
                date = format.parse(dateString);
            } catch (ParseException e) {
                logger.error("解析时间格式失败！");
            }
        }
        return date;
    }

    /***
     * 默认转换为yyyy-MM-dd HH:mm:ss格式
     * @param date
     * @return
     */
    public static String dateToStr(Date date) {
        return Objects.isNull(date) ? "" : SDF_YYYY_MM_DD_HH_MM_SS.format(date);
    }

    /***
     * EEE MMM dd HH:mm:ss zzz yyyy
     * THE.USA nowDate
     * @return {@link Date}
     */
    public static String getUsaYyyyMmDdHhMmSs() {
        return format(now(), USA_YYYY_MM_DD_HH_MM_SS);
    }

    /***
     * yyyy/MM/dd HH:mm:ss
     * @return {@link Date}
     */
    public static String getTwoYyyyMmDdHhMmSs() {
        return format(now(), TWO_YYYY_MM_DD_HH_MM_SS);
    }

    /***
     * MMddHHmmss
     * @return {@link Date}
     */
    public static String getThreeMmDdHhMmSs() {
        return format(now(), THREE_MMDDHHMMSS);
    }

    /***
     * yyyy/MM/dd
     * @return {@link Date}
     */
    public static String getTwoYyyyMmDd() {
        return format(now(), TWO_YYYY_MM_DD);
    }

    /***
     * yyyyMMddHHmmss
     * @return {@link Date}
     */
    public static String getThreeYyyyMmDdHhMmSs() {
        return format(now(), THREE_YYYYMMDDHHMMSS);
    }

    /***
     * yyyy-MM-dd
     * @return {@link Date}
     */
    public static String getOneYyyyMmDd() {
        return format(now(), ONE_YYYY_MM_DD);
    }

    /***
     * yyyy-MM-dd HH:mm
     * @return {@link Date}
     */
    public static String getOneYyyyMmDdHhMm() {
        return format(now(), ONE_YYYY_MM_DD_HH_MM);
    }

    /***
     * yyyy/MM/dd HH:mm
     * @return {@link Date}
     */
    public static String getTwoYyyyMmDdHhMm() {
        return format(now(), TWO_YYYY_MM_DD_HH_MM);
    }

    /***
     * yyyyMMddHHmm
     * @return {@link Date}
     */
    public static String getThreeYyyyMmDdHhMm() {
        return format(now(), THREE_YYYYMMDDHHMM);
    }

    public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    /**
     * 返回当前时间
     *
     * @return Date实例
     */
    public static Date now() {
        return nowCal().getTime();
    }

    /**
     * 当前时间
     *
     * @return Calendar实例
     */
    public static Calendar nowCal() {
        return Calendar.getInstance();
    }

    /**
     * 请求限制处理
     */
    private void doRequestLimit(HttpServletRequest request) {
        // 60秒钟200个请求处理
        // 判断开始时间到现在过去了多长时间，是否超过1分钟
        LocalDateTime now = LocalDateTime.now();
        Duration duration = Duration.between(now, now);
//      boolean isLimit = duration.toMillis() <= requestLimit && requestSum >= requestSumLimit;
//      if (isLimit) {
//         try {
//            Thread.sleep(requestLimit - duration.toMillis());
//         } catch (InterruptedException e) {
//            e.printStackTrace();
//         }
//         requestSum = 0;
//         beginTime = now;
//      }
//      requestSum++;
    }
}
